#include "smSourceCode.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdlib.h>
using namespace std;

namespace ShaderManager
{



smSourceCode::smSourceCode(const string& filename)
{
	int line_number = 1;
	code = LoadSource(filename, line_number);
}

smSourceCode::~smSourceCode()
{

}

string smSourceCode::LoadSource(string filename, int &linen)
{
	string source;
	string filename_path = filename.substr( 0, filename.find_last_of( '\\' ) +1 );
	string filename_file = filename.substr( filename.find_last_of( '\\' ) +1 );

	ifstream file(filename.data(), ios::in);
	
	if(!file) 
	{
		cerr << "Could not open file " << filename << endl;
	}
	
	int current_line = 1;

	filenames.push_back(filename);
	lines.push_back(linen);
	locallines.push_back(current_line);

	while(!file.eof())
	{
		string line;
		getline(file, line);
		int pos = line.find("#include");
		if(pos >= 0)
		{
			int pos_begin = line.find("\"", pos) + 1;
			int pos_end = line.find("\"", pos_begin) - 1;
			if(pos_begin>=pos_end)
			{
				cout << "Error in file "<< filename << " at line " << current_line << " : include failed." << endl;
				return source;
			}

			string include_name = line.substr(pos_begin, pos_end-pos_begin+1);
			source += LoadSource(filename_path+include_name, linen);
			filenames.push_back(filename);
			lines.push_back(linen);
			current_line++;
			locallines.push_back(current_line);
		}
		else
		{
			source += line;
			source += "\n";
			linen++;
			current_line++;
		}
	}

	file.close();  // on ferme le fichier
	return source;
}

char * smSourceCode::getCode()
{
	char * code_char = new char[code.size()+1];
	for(unsigned int i=0 ; i<code.size() ; ++i)
		code_char[i] = code.data()[i];
	code_char[code.size()] = '\0';

    return code_char;
}

void smSourceCode::displayOpenglLog(const string openGLlog)
{
	cout << "GLSL ERROR LOG" << endl;

	istringstream log(openGLlog,istringstream::in);

	while(!log.eof())
	{
		string linelog;
		getline(log, linelog);

		int pos_begin = linelog.find("0(", 0) + 2;
		int pos_end = linelog.find(") : error", pos_begin) - 1;

		if(pos_end > pos_begin)
		{
			char * line_number_char = new char[pos_end-pos_begin+2];
			for(int i=pos_begin ; i <= pos_end ; ++i)
				line_number_char[i-pos_begin] = linelog.data()[i];
			line_number_char[pos_end-pos_begin+1] = '\0';
			int line_number = atoi(line_number_char);

			int v;

			for(unsigned int i=0 ; i < lines.size() ; ++i)
			{
				// on the last one
				if( i == lines.size()-1 )
				{
					v = i;
					break;
				}
				
				if(line_number < lines[i+1])
				{
					v = i;
					break;
				}
			}

			cout << linelog << endl;
			cout << "File " << filenames[v] << " line " << line_number-lines[v]+locallines[v] << endl;
			line_number = line_number;
		}
		else
		{
			cout << linelog << endl;
		}
	}
}

}